package com.github.cooingandwooing.process;

import java.util.List;

import cn.hutool.core.net.url.UrlBuilder;
import cn.hutool.core.net.url.UrlQuery;
import com.github.cooingandwooing.constant.SpiderConstant;
import com.github.cooingandwooing.model.CaseInfoDto;
import com.github.cooingandwooing.model.HuayuShouyeResponse;
import com.github.cooingandwooing.utils.HuayuUrlBuilder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Html;
import us.codecraft.webmagic.selector.Selectable;

import org.springframework.stereotype.Component;

import static org.apache.http.Consts.UTF_8;

/**
 * 〈GitHubProcessor 〉
 *
 * @author Administrator
 * @since 1.0.0
 */
@Slf4j
@Component
public class HuayuProcessor implements PageProcessor {
    /**
     * 列表页就抓取 url 如果详情页就抓取 案件信息
     * @param page
     */
    @Override
    public void process(Page page) {

        String pageRequestUrl = page.getUrl().toString();
        if (StringUtils.isNotBlank(pageRequestUrl)) {
            // 如果请求是详情页 则获取案件信息 并保存 page.putField("", )
            if (StringUtils.startsWith(pageRequestUrl, "http://132.36.1.7/ajxq/ajxq.do?action=queryMainTable")) {
                List<CaseInfoDto> caseInfoDtoList = page.getJson().toList(CaseInfoDto.class);
                page.putField("caseInfoDtoList", caseInfoDtoList);
                // 获取案件 编码和类别
                UrlQuery urlQuery = UrlBuilder.of(pageRequestUrl, UTF_8).getQuery();
                String cBhAj = urlQuery.get("cBhAj").toString();
                String nAjlb = urlQuery.get("nAjlb").toString();
                page.putField("cBhAj", cBhAj);
                page.putField("nAjlb", nAjlb);
            }
            // 列表页
            else if (StringUtils.startsWith(pageRequestUrl, "http://132.36.1.89:8081/tjfx/artery/report/dealParse.do?action=parse")) {
                // 如果请求是列表页 则获取 详情页 url
                HuayuShouyeResponse huayuShouyeResponse = page.getJson().toObject(HuayuShouyeResponse.class);
                // 解析页面获取案件的详情 url 地址
                if (StringUtils.isNotBlank(huayuShouyeResponse.getTableHtml())) {
                    String tableHtml = huayuShouyeResponse.getTableHtml();
                    // 案件信息列表
                    Html htmlTr = new Html(tableHtml);
                    List<Selectable> table_tr = htmlTr.xpath("//table[@class=reportTable]/tbody/tr[@class!=crs_tr_fixed and @class!=reportTabLastTr]")
                            .nodes();
                    if (table_tr.size() > 0 && table_tr.size() <= 10) {
                        for (int i = 0; i < table_tr.size(); i++) {
                            String tdStr = table_tr.get(i).toString();
                            // log.info("获取案件{}的信息...", table_tr.get(i).nodes().toString());
                            // 取出案件编号
                            Html htmlTd = new Html(tdStr);
                            // 下面注释是测试另外一种方式获取链接
/*                    String temp = htmlTd.xpath("//table[@class=crst]/tbody/tr/td/a").links().regex("\"CBhAj\":"
                            + "(./?)},\"type\":", 1).get();*/
                            // 取出案件链接
                            String linkOfCaseInfo = htmlTd.xpath("//table[@class=crst]/tbody/tr/td/a").links().get();
                            // 案件编号
                            String cBhAj = StringUtils.substringBetween(linkOfCaseInfo, "\"CBhAj\":\"", "\"},\"type\"");
                            // 新案件类别
                            String nAjlb = StringUtils.substringBetween(linkOfCaseInfo, "\"NAjlb\":\"", "\",\"CBhLcsl\"");
                            if (StringUtils.isNoneBlank(cBhAj, nAjlb)) {
                                /**
                                 * 获取案件详情信息
                                 */
                                String caseInfoUrl = HuayuUrlBuilder.getCaseInfoUrl(cBhAj, nAjlb);
                                if (StringUtils.isNotBlank(caseInfoUrl)) {
                                    page.addTargetRequest(caseInfoUrl);
                                }

                            }
                        }
                    }
                    /**
                     * 获取总记录数  本页记录数 第几页 总页数
                     */
                    String pageHtml = huayuShouyeResponse.getPageHtml();
                    Html htmlPage = new Html(pageHtml);

                    String pageStr = htmlPage.css("td", "allText").toString().trim();
                    // 页次:1 / 230页 本页记录数 10 总记录数 2294 分页：1 2 3 4 5 6 7 8 9 10 > >> 到: 记录数:
                    // 页次:1/256页本页记录数10总记录数2551分页：12345678910>>>到:记录数:
                    pageStr = StringUtils.deleteWhitespace(pageStr);
                    if (StringUtils.isNotBlank(pageStr) && StringUtils.contains(pageStr, "页次")) {
                        long total = Long.valueOf(StringUtils.substringBetween(pageStr, "总记录数", "分页"));
                        long current = Long.valueOf(StringUtils.substringBetween(pageStr, "页次:", "/"));
                        long size = Long.valueOf(StringUtils.substringBetween(pageStr, "本页记录数", "总记录数"));
                        long totalPageSize = Long.valueOf(StringUtils.substringBetween(pageStr, "/", "页本页记录数"));
                        // 有下一页 则取下一页 添加到目录里面
                        if (current <= total) {
                            // 从第1页开始，所以模运算等于1，SpiderConstant.LIST_OF_CASE_INTERVAL 指的是间隔几个数，批量加入
                            if (current % SpiderConstant.LIST_OF_CASE_INTERVAL == 1) {
                                for (int i = 1; i <= SpiderConstant.LIST_OF_CASE_INTERVAL; i++) {
                                    if (current + i <= total) {
                                        String nextUrl = HuayuUrlBuilder.getNextPageUrlOfNewCases(page.getUrl()
                                                        .toString(),
                                                current + i);
                                        page.addTargetRequest(nextUrl);
                                        log.info("将新收列表页，第{}页的加入获取目标 url 中...", current + i);
                                    }
                                }
                            }
                        }
                    }
                    else {
                        // 没有取到页码信息，重新将本页加入 TargetRequest，重新获取
                        page.addTargetRequest(page.getUrl().toString());
                        log.warn("没有取到页码信息，重新将本页加入 TargetRequest，重新获取,url：{}", page.getUrl().toString());
                    }
                    // 列表页 page 跳过
                    page.setSkip(true);
                }
            }
            // 有时候会跳入站点首页 非第一页
            else if (StringUtils.startsWith(pageRequestUrl, "http://132.36.1.7/sym/")) {
                // 如果是首页 则重新 新收第一页
                page.addTargetRequest(HuayuUrlBuilder.buildUrlListNewCases());
                log.warn("遇到首页，首页 url 重新加入,url：{}", page.getUrl().toString());
                page.setSkip(true);
            }
        }
        else {
            log.warn("url 为空！，请查看{}", page.getUrl().toString());
        }
    }

    @Override
    public Site getSite() {
        // 如何解析页面
        return Site.me()
                .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65.0) Gecko/20100101 " + "Firefox/65.0")
                .addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")
                .addHeader("Accept-Encoding", "gzip, deflate").addHeader("Connection", "keep-alive")
                .addHeader("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2")
                .setCharset("utf-8") // 设置编码gbk
                .setTimeOut(600 * 1000) // 设置超时时间
                .setRetrySleepTime(3000) // 设置重试的间隔时间
                .setRetryTimes(20) // 设置重试的次数
                .setCycleRetryTimes(10000);// 设置循环重试次数

    }
}